<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
namespace App\Service\Redis;

use App\Constants\ErrorCode;
use App\Exception\BusinessException;
use App\Model\User;
use Hyperf\Redis\Redis;
use Hyperf\Utils\Codec\Json;
use Hyperf\Utils\Traits\StaticInstance;

class UserAuth
{
    use StaticInstance;

    const X_TOKEN = 'X-Token';

    const TTL = 86400;

    public $userId;

    public $mobile;

    public $token;

    public function reload(string $token)
    {
        $content = di()->get(Redis::class)->get($this->getToken($token));
        if (empty($content)) {
            return $this;
        }

        $data = json_decode($content, true) ?? [];
        if (! isset($data['id']) || ! isset($data['mobile'])) {
            return $this;
        }

        $this->token = $token;
        $this->userId = $data['id'];
        $this->mobile = $data['mobile'];
        return $this;
    }

    public function build()
    {
        if (! isset($this->userId) || ! isset($this->mobile)) {
            throw new BusinessException(ErrorCode::TOKEN_INVALID);
        }

        return $this;
    }

    public function init(User $user, ?string $token = null)
    {
        if (empty($token)) {
            $token = md5($user->id . uniqid());
        }

        di()->get(Redis::class)->set($this->getToken($token), Json::encode([
            'id' => $user->id,
            'mobile' => $user->mobile,
        ]), ['EX' => self::TTL]);

        $this->userId = $user->id;
        $this->mobile = $user->mobile;
        $this->token = $token;

        return $this;
    }

    protected function getToken(string $token): string
    {
        return 'auth:' . $token;
    }
}
